package com.le.core.config;

import com.le.core.login.domin.LoginUser;
import com.le.core.security.filter.JwtAuthenticationTokenFilter;
import com.le.core.security.handle.AuthenticationEntryPointImpl;
import com.le.core.security.handle.LogoutSuccessHandlerImpl;
import com.le.core.web.service.impl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


@Configuration
public class SecurityConfig {

    /**
     * token认证过滤器
     */
    @Autowired
    private JwtAuthenticationTokenFilter authenticationTokenFilter;

    /**
     * 认证失败处理类
     */
    @Autowired
    private AuthenticationEntryPointImpl unauthorizedHandler;

    /**
     * 退出处理类
     */
    @Autowired
    private LogoutSuccessHandlerImpl logoutSuccessHandler;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;


    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        /**
         * authorizeHttpRequests:针对http请求进行授权配置
         */
        http.authorizeHttpRequests(auth->
                auth
                        /**
                         * requestMatchers 路由匹配
                         * hasRole 角色
                         * hasAnyRole 多角色
                         */
                        //.requestMatchers("/wechat/login").hasRole("wechat")
                        //.requestMatchers("/pass/login").hasAnyRole("pass","user")

                        /**
                         * hasAuthority 权限
                         * hasAnyAuthority 多权限
                         */
                        //.requestMatchers("/wechat/login").hasAuthority("wechat:api")
                        //.requestMatchers("/pass/login").hasAnyAuthority("pass:api","admin:api")

                        /**
                         * 路由匹配规则：
                         *  ?	任意单个字符
                         *  *	0到任意数量的字符
                         *  **	0到任意个目录
                         */
                        //.requestMatchers("/login/?").hasAuthority("admin:api")
                        //.requestMatchers("/login/*").hasAuthority("admin:api")
                        //.requestMatchers("/login/**").hasAuthority("admin:api")

                        /**
                         * permitAll 用户可以任意访问
                         * anonymous 匿名可以访问
                         * denyAll 用户不能访问
                         */
                        .requestMatchers("/password/login","/phone/login","/wechat/login").anonymous()
                        //.requestMatchers("/wechat/login").denyAll()
                        //.requestMatchers("/wechat/login").permitAll()

                        /**
                         * anyRequest 其他路由
                         * authenticated 需要验证
                         */
                        .anyRequest().authenticated()
        );

        /**
         * 认证失败处理
         */
        http.exceptionHandling(exception->
                exception.
                        authenticationEntryPoint(unauthorizedHandler)
        );


        /**
         * 前后端 无状态请求 一般用不到
         * loginPage:登录页面
         * loginProcessingUrl:登录接口 过滤器
         * defaultSuccessUrl:登录成功之后访问的页面
         */
        http.formLogin(formLogin->
                formLogin.disable()
//                        .loginPage("/login").permitAll()
//                        .loginProcessingUrl("/login")
//                        .defaultSuccessUrl("/index")

        );

        /**
         * 无状态请求就可以直接关闭 csrf
         */
        //http.csrf(Customizer.withDefaults());
        http.csrf(csrf->csrf.disable());


        /**
         * 基于token，所以不需要session
         */
        http.sessionManagement(session->session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));


        /**
         * 退出处理类
         */
        http.logout(logout->
                logout
//                        .disable()
                        .logoutUrl("/logout")
                        .logoutSuccessHandler(logoutSuccessHandler)
        );

        /**
         * token 添加过滤器
         */
        http.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    /**
     * 强散列哈希加密实现
     */
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder()
    {
        return new BCryptPasswordEncoder();
    }

    /**
     * AuthenticationManager
     *
     * @return
     * @throws Exception
     */
    @Bean
    AuthenticationManager authenticationManager() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        ProviderManager pm = new ProviderManager(daoAuthenticationProvider);
        return pm;
    }

}
